﻿//======================================================================
//
//        Copyright : Zhengzhou Strawberry Computer Technology Co.,LTD.
//        All rights reserved
//        
//        Application:NRapid MVC framework
//        Filename :MagicViewBag.cs
//        Description :控制器父类
//
//        created by Lucas at  2015-6-30`
//     
//        WebSite:http://www.NRapid.com
//
//======================================================================
using System;
using System.Web;
using System.Collections.Generic;
using System.IO;

namespace NRapid
{
    /// <summary>
    /// 魔法Action,包含一些需要生成器重写实现的函数
    /// </summary>
    public class MagicAction
    {
        public delegate void __Render__(NameValueCollection nvc);
        public __Render__ __render__ = null;
        public virtual string postEventArgumentID { get { return null; } }
        public virtual string postEventSourceID { get { return null; } }
        /// <summary>
        /// 插入Csharp代码段
        /// </summary>
        /// <param name="textFilePath">含有csharp代码的文本文件路径</param>
        public virtual void InsertCodeSegment(string textFilePath) { }
        /// <summary>
        /// 插入Csharp类文件函数中的代码段
        /// </summary>
        /// <param name="classFilePath">csharp类文件路径</param>
        /// <param name="methodName">类文件中的函数名</param>
        public virtual void InsertCodeSegment(string classFilePath, string methodName) { }
        /// <summary>
        /// 渲染html模板
        /// </summary>
        /// <param name="tplPath">模板相对路径,一般相对于App/Views/Default目录</param>
        public virtual void View(string tplPath) { }
        /// <summary>
        /// 渲染html模板
        /// </summary>
        /// <param name="name">模板样式</param>
        /// <param name="tplPath">模板相对路径,一般相对于App/Views/Default目录</param>
        public virtual void View(string name, string tplPath) { }
    }
    /// <summary>
    /// 请求类型
    /// </summary>
    public enum MethodType
    {
        NONE = 0,
        POST = 1,
        GET = 2,
        PUT = 3,
        DELETE = 4,
        AJAX = 5
    }
    /// <summary>
    /// 请求的内容类型
    /// </summary>
    public enum ContentType
    {
        NONE = 0,
        Application_x_www_form_urlencoded = 1,
        Multipart_form_data = 2,
        Application_json = 3,
        Text_xml = 4,
        Application_octet_stream=5
    }
    /// <summary>
    /// 服务器类型
    /// </summary>
    public enum ServerType
    {
        /// <summary>
        /// NRapid实现的Owin服务器
        /// </summary>
        NRapidOwin,
        /// <summary>
        /// 无服务器，静态页生成
        /// </summary>
        IsStatic,
        /// <summary>
        /// 未知
        /// </summary>
        UnKnown
    }
    /// <summary>
    /// NRapid的控制器基类，核心类，类似于asp.net中的page类
    /// </summary>
    public class BaseAction : MagicAction, IDisposable
    {
        /// <summary>
        /// Html输出类
        /// </summary>
        public NRapid.Owin.HtmlWriter htmlWriter = null;
        public NRapid.Owin.Request request = null;
        /// <summary>
        /// 服务器类型
        /// </summary>
        public ServerType _serverType = ServerType.UnKnown;
        /// <summary>
        /// 从get和post中获取的请求参数
        /// </summary>
        public NameValueCollection _get = null;
        /// <summary>
        /// 从前端传过来的文件
        /// </summary>
        public Dictionary<string, HttpFile> _files = null;
        /// <summary>
        /// 页面输出对象，类似于response.output对象。
        /// </summary>
        public TextWriter _tw = null;
        /// <summary>
        /// 页面的二级域名
        /// </summary>
        public string _subdomain;//二级域名
        /// <summary>
        /// 页面的模块名
        /// </summary>
        public string _app;
        /// <summary>
        /// 请求的url
        /// </summary>
        public string _url;
        /// <summary>
        /// 请求的方法，get,post
        /// </summary>
        public NRapid.MethodType _methodType = NRapid.MethodType.NONE;
        private bool _isMobile = false;
        /// <summary>
        /// 请求是否来自移动端
        /// </summary>
        public bool isMobile
        {
            get
            {
                string agent = null;
                if (this._serverType == ServerType.NRapidOwin)
                {
                    if (request.headers.ContainsKey("User-Agent"))
                    {
                        agent = request.headers["User-Agent"][0];
                    }
                }
                else
                {
                    return _isMobile;
                }
                string[] keywords = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" };

                //排除 Windows 桌面系统  
                if (!agent.Contains("Windows NT") || (agent.Contains("Windows NT") && agent.Contains("compatible; MSIE 9.0;")))
                {
                    //排除 苹果桌面系统  
                    if (!agent.Contains("Windows NT") && !agent.Contains("Macintosh"))
                    {
                        foreach (string item in keywords)
                        {
                            if (agent.Contains(item))
                            {
                                _isMobile = true;
                                break;
                            }
                        }
                    }
                }
                return _isMobile;
            }
            set
            {
                _isMobile = value;
            }
        }
        /// <summary>
        /// 请求返回的页面类型
        /// </summary>
        public string ContentType
        {
            set
            {
                if (this._serverType == ServerType.NRapidOwin)
                {
                   
                }
            }
            get
            {
                if (this._serverType == ServerType.NRapidOwin)
                {

                }
                return null;
            }
        }
        /// <summary>
        /// 插入Csharp代码段
        /// </summary>
        /// <param name="textFilePath">含有csharp代码的文本文件路径</param>
        public sealed override void InsertCodeSegment(string textFilePath)
        {
        }
        /// <summary>
        /// 插入Csharp类文件函数中的代码段
        /// </summary>
        /// <param name="classFilePath">csharp类文件路径</param>
        /// <param name="methodName">类文件中的函数名</param>
        public sealed override void InsertCodeSegment(string classFilePath, string methodName)
        {
        }
        /// <summary>
        /// 模板渲染前函数，用于子类重写
        /// </summary>
        public virtual void Before()
        {

        }
        /// <summary>
        /// 模板渲染后函数，用于子类重写
        /// </summary>
        public virtual void After()
        {

        }

        #region 初始化函数
        /// <summary>
        /// 初始化函数
        /// </summary>
        public BaseAction()
        {
            this._serverType = ServerType.UnKnown;
        }
        private static string rootDir = null;
        /// <summary>
        /// 返回服务器路径
        /// </summary>
        /// <param name="path">相对路径</param>
        /// <returns></returns>
        public static string MapPath(string path)
        {
            return NRapid.Utility.MapPath(path);
        }
        /// <summary>
        /// 静态html页输出初始化函数
        /// </summary>
        /// <param name="fileName"></param>
        public BaseAction(string fileName)
        {
            this._serverType = ServerType.IsStatic;
            System.IO.StreamWriter sw = null;// new System.IO.StreamWriter(MapPath(fileName), false, System.Text.Encoding.UTF8);
            sw =new StreamWriter( File.OpenWrite(MapPath(fileName)));
            this._tw = sw;
        }
        public BaseAction(Owin.HtmlWriter writer)
        {
            this._serverType = ServerType.NRapidOwin;
            this.htmlWriter = writer;
            this._tw = writer.writer;
        }
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="action"></param>
        public BaseAction(BaseAction action)
        {
            action._serverType = this._serverType;
            action._methodType = this._methodType;
            action._subdomain = this._subdomain;
            action._url = this._url;
            action._get = this._get;
            action._files = this._files;
            action._app = this._app;
        }
        /// <summary>
        /// 关闭资源
        /// </summary>
        public void Close()
        {
            htmlWriter.Close();
            this._tw.Dispose();
        }
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (!_isDisposed)
            {
                this._tw.Dispose();
                if (htmlWriter != null)
                {
                    htmlWriter.Close();
                    htmlWriter.Dispose();
                }
                if (_files != null)
                {
                    foreach (var file in _files)
                    {
                        file.Value.Value.Dispose();
                    }
                }
            }
            _isDisposed = true;
        }
        private bool _isDisposed = false;
        /// <summary>
        /// 基于文本输出对象的初始化函数
        /// </summary>
        /// <param name="tw">文本输出对象</param>
        public BaseAction(System.IO.TextWriter tw)
        {
            this._serverType = ServerType.IsStatic;
            this._tw = tw;
        }
        #endregion
        #region 输出函数
        /// <summary>
        /// 输出文本并输出<br/>
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="obj">对象</param>
        public void WriteLine<T>(T obj)
        {
            Write(obj);
            Write("<br/>");
        }
        /// <summary>
        /// 输出文本对象
        /// </summary>
        /// <param name="obj">字符串</param>
        public void Write(string obj)
        {
            if (obj == null)
                return;
            if (_serverType == ServerType.NRapidOwin)
            {
                htmlWriter.Write(obj);
            }
            else if (_serverType == ServerType.IsStatic)
            {
                _tw.Write(obj);
            }
        }
        /// <summary>
        /// 把对象转为字符串并输出
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="obj">对象</param>
        public void Write<T>(T obj)
        {
            if (obj == null) return;
            if (_serverType == ServerType.NRapidOwin)
            {
                htmlWriter.Write(obj.ToString());
            }
            else if (_serverType == ServerType.IsStatic)
            {
                _tw.Write(obj);
            }
        }
        /// <summary>
        /// 输出字节流，用于输出二进制流，如图象，文件等。
        /// </summary>
        /// <param name="buffer"></param>
        public void Write(byte[] buffer)
        {
            if (this._serverType == ServerType.NRapidOwin)
            {
                htmlWriter.Write(buffer);
            }
        }
        #endregion
        #region Ajax返回数据
        /// <summary>
        /// 返回数据库实体类对应的json对象{code:1,msg:"",result:[json对象]}
        /// </summary>
        /// <param name="obj">数据库实体类</param>
        public void AjaxReturn(dynamic obj)
        {
            AjaxReturn(obj.ToJson());
        }
        /// <summary>
        /// 返回数据库实体类对应的json对象{code:1,msg:"",result:[json对象]}
        /// </summary>
        /// <param name="str">数据库实体类</param>
        public void AjaxReturn(Struct str)
        {
            if (str == null)
            {
                AjaxReturn("null");
            }
            else
            {
                AjaxReturn(str.ToJson());
            }
        }
        /// <summary>
        /// 返回数据库实体类对应的json对象{code:[code状态码],msg:"",result:[json对象]}
        /// </summary>
        /// <param name="str">数据库实体类</param>
        /// <param name="code">状态码</param>
        public void AjaxReturn(Struct str, int code)
        {
            if (str == null)
            {
                AjaxReturn("null", code);
            }
            else
            {
                AjaxReturn(str.ToJson(), code);
            }
        }
        /// <summary>
        /// 返回数据库实体类对应的json对象{code:[code状态码],msg:[msg消息],result:[json对象]}
        /// </summary>
        /// <param name="str">数据库实体类</param>
        /// <param name="code">状态码</param>
        /// <param name="msg">消息</param>
        public void AjaxReturn(Struct str, int code, string msg)
        {
            if (str == null)
            {
                AjaxReturn("null", code, msg);
            }
            else
            {
                AjaxReturn(str.ToJson(), code, msg);
            }
        }
        /// <summary>
        /// 返回json{code:1,msg:"",result:[json字符串]}
        /// </summary>
        /// <param name="json">json字符串</param>
        public void AjaxReturn(string json)
        {
            AjaxReturn(json, 1, "");
        }
        /// <summary>
        /// 返回json{code:[code状态码]}
        /// </summary>
        /// <param name="code">状态码</param>
        public void AjaxReturn(int code)
        {
            this.ContentType = "application/json;charset=utf-8";
            this.Write(string.Format("{{\"code\":{0}}}", code));
        }
        /// <summary>
        /// 返回json{code:[code状态码],msg:"",result:[json字符串]}
        /// </summary>
        /// <param name="json">json字符串</param>
        /// <param name="code">状态码</param>
        public void AjaxReturn(string json, int code)
        {
            AjaxReturn(json, code, "");
        }
        /// <summary>
        /// 返回json字符串{code:[code状态码],msg:[msg消息],result:[json字符串]}
        /// </summary>
        /// <param name="json">json字符串</param>
        /// <param name="code">状态码</param>
        /// <param name="msg">消息</param>
        public void AjaxReturn(string json, int code, string msg)
        {
            this.ContentType = "application/json;charset=utf-8";
            this.Write(string.Format("{{\"code\":{0},\"msg\":\"{1}\",\"result\":{2}}}", code, msg, json));
        }
        /// <summary>
        /// 返回json字符串{code:[code状态码],msg:[msg消息]}
        /// </summary>
        /// <param name="code">状态码</param>
        /// <param name="msg">消息</param>
        public void AjaxReturn(int code, string msg)
        {
            this.ContentType = "application/json;charset=utf-8";
            this.Write(string.Format("{{\"code\":{0},\"msg\":\"{1}\"}}", code, msg));
        }
        /// <summary>
        /// 返回true或false
        /// </summary>
        /// <param name="obj">bool变量</param>
        public void AjaxReturn(bool obj)
        {
            this.ContentType = "application/json;charset=utf-8";
            this.Write(obj ? "true" : "false");
        }
        /// <summary>
        /// 返回表数据对象对应的json字符串{code:[code状态码],msg:[msg消息],result:[表数据对应的json对象]}
        /// </summary>
        /// <typeparam name="T">表数据，NRapid.List对象</typeparam>
        /// <param name="obj">表数据对应的json对象</param>
        public void AjaxReturn<T>(NRapid.List<T> obj)
        {
            this.AjaxReturn(obj.ToJson(), obj ? 1 : 0);
        }
        #endregion
        /// <summary>
        /// 渲染模板
        /// </summary>
        /// <param name="tplPath">模板相对路径</param>
        public sealed override void View(string tplPath)
        {

        }
        /// <summary>
        /// 渲染模板
        /// </summary>
        /// <param name="name">文件夹名</param>
        /// <param name="tplPath">模板文件夹名</param>
        public sealed override void View(string name, string tplPath)
        {

        }
        /// <summary>
        /// 页面重定向
        /// </summary>
        /// <param name="url">重定向url</param>
        public void Redirect(string url)
        {
            if (this._serverType == ServerType.IsStatic)
            {
                _tw.Write("jump error!");
            }
        }
        /// <summary>
        /// 返回ng-controller
        /// </summary>
        /// <param name="ngController">ngController</param>
        /// <param name="javascript">javascript字符串</param>
        public void AngularControllerReturn(string ngController, string javascript)
        {
            this.ContentType = "application/json;charset=utf-8";
            this.Write(string.Format("function {0}($scope){{", ngController));
            this.Write(javascript);
            this.Write("}");
        }
        /// <summary>
        /// 返回ng-controller
        /// </summary>
        /// <param name="ngController">ngController</param>
        /// <param name="ngModel">ngModel</param>
        /// <param name="json">json字符串</param>
        public void AngularControllerReturn(string ngController, string ngModel, string json)
        {
            this.ContentType = "application/json;charset=utf-8";
            this.Write(string.Format("function {0}($scope){{$scope.{1}={2};}}", ngController, ngModel, json));
        }
        /// <summary>
        /// 返回ng-controller
        /// </summary>
        /// <param name="ngController">ngController</param>
        /// <returns></returns>
        public AngularControllerBuilder AngularController(string ngController)
        {
            this.ContentType = "application/json;charset=utf-8";
            return new AngularControllerBuilder(this, ngController);
        }
    }
}